#include "informacionDiscos.h"

t_infoDisco *seleccionarDiscoAAsignarPet(t_list *tablaDisco,t_peticion * peticion){

	int cant=0;
	t_infoDisco *discoMinPet = (t_infoDisco*)collection_list_get(tablaDisco,cant);

	while (cant <= collection_list_size(tablaDisco)){

		cant++;

		t_infoDisco *disco = (t_infoDisco*)collection_list_get(tablaDisco,cant);
		if (cantidadPeticiones(disco) < cantidadPeticiones(discoMinPet)){
			if (disco->estado == Sincronizando){
				if(peticion->flagSincro != 1){
					if(disco->sectoresCopiados >= peticion->sPayload->nSector) {
						discoMinPet = disco;
					}
				}
			}else{
				discoMinPet = disco;
			}
		}
	}

	return discoMinPet;
}

void agregarPeticionACola(t_queue *peticionesDisco, t_peticion *peticion, t_infoDisco *disco){

/* Enviar msj socket al PPD*/
   t_stream *stream = codificarPaquete(peticion);
   if (socket_enviarPeticionPPD(disco->nroSocket, stream->data) > 0)
   {
	   /* Agregar a la cola de peticiones de disco y falta enviar msj a PPD*/
		collection_queue_push(peticionesDisco, peticion);
   }
	/* Si el msj llega bien entonces:*/
   if(peticion->tipoPeticion == Lectura){
	   /*Es una lectura*/
	   printf("Se ha efectuado una lectura en el disco ID:%i", disco->idDisco);
	   	   logMessage(LOG_INFO,"Realizo una lectura sobre: %s", disco);
   }
   /*Logueo a quien escribiro y que opéracion hizo*/
	/* Si el msj es error (no encontro el ppd) COMIENZO RUTINA DE DISTRIBUCION DE PETICIONES*/
}

t_peticion *getPeticionResuelta(t_socket_client *client){

	t_list *petResueltas = getListaPeticionesResueltas();
	return petResueltas;
}

void *destruirPayload (t_payload *payload){
	free(payload->data);
	free(payload);
}

void *destruirPeticion (t_peticion *peticion){
	destruirPayload(peticion->sPayload);
	free (peticion);
}

int cantidadPeticiones(t_infoDisco *disco){
    return collection_queue_size(disco->colaPendientesPetDisco);
}

t_infoDisco* inicializarInfoDisco(int idDisco){

	t_infoDisco* disco = malloc(sizeof(t_infoDisco));
	disco->idDisco = idDisco;
	disco->estado = Sincronizando;
	disco->colaPendientesPetDisco = collection_queue_create();
	disco->sectoresCopiados = 0;
	disco->colaSectoresCopiados = collection_queue_create();
	disco->soyDiscoD = 0;
	disco->nroSocket = 0; /*ESTA BIEN INICIALIZARLO CON 0, SI DESPUES LE ASIGNA EL SOCKET???*/
	disco->tid = /*CUANDO LO ASIGNA????*/
	disco->tiempoInicio = 0;

	return disco;
}

t_infoDisco* clousreBuscarDiscoByIp(t_list *tablaDisco, char* ip){
	int cant = 0;
	t_infoDisco *disco = NULL;
	while (cant < collection_list_size(tablaDisco)){
		disco = collection_list_get(tablaDisco, cant);
		if (strcmp(sockets_getIp(disco->nroSocket->socket),ip) == 0){
			return disco;
		}
		else
			cant ++;
	}
	return NULL;
}

void agregarATablaDisco(t_list *tablaDisco, t_infoDisco *disco, char *ipClient){

	/*Agrego el disco en la tabla de disco*/
	disco->nroSocket = sockets_createClient(ipClient, getConfig()->puertoSendPPD);

	if (collection_list_size(tablaDisco) == 0 && first==0){
		/*Se conecto el disco D*/
		printf("Raid ACTIVO");
		first = 1;
        disco->estado = Activo;
        disco->soyDiscoD = 1;
        collection_list_add(tablaDisco, disco);
        printf("Se ha conectado un nuevo disco ID:%i", disco->idDisco);
	} else{
        disco->estado = Sincronizando;
        collection_list_add(tablaDisco, disco);
        printf("Se ha conectado un nuevo disco ID:%i", disco->idDisco);

        generarThreadSincronizacion();
    }

}

t_infoDisco *clousreBuscarDiscoById(int idDisco){

	t_list *listInfoDisco = getListaInfoDisco();
	int i;
	for (i =0; i <= collection_list_size(listInfoDisco); i++){
		t_infoDisco* infoDisco = collection_list_get(listInfoDisco, i);
		if (infoDisco->idDisco == idDisco){
			return infoDisco;
		}
	}
	return NULL;
}

t_peticion *inicializarPeticion(){
	t_peticion* peticion = (t_peticion*)malloc(sizeof(t_peticion));
	peticion->sPayload = (t_payload*)malloc(sizeof(t_payload));

	return peticion;
}

t_peticion *decodificacionPaquete(char *mensaje){

   t_peticion* paquete = inicializarPeticion();

   int 	offset = 0,	tmp_size = 0 ;
   memcpy (paquete->tipoPeticion,mensaje, tmp_size = sizeof(char));
   offset = tmp_size;
   memcpy (paquete->length ,mensaje + offset ,tmp_size = sizeof(short));
   offset += tmp_size;
   /*tama�o del sector 4 bytes*/
   memcpy (paquete->sPayload->nSector, mensaje + offset, tmp_size = sizeof(int));
   offset += tmp_size;
   /*tama�o del offset 2 bytes*/
   paquete->sPayload->data = malloc(sizeof(BUFFERSIZEPAYLOAD));
   memcpy (paquete->sPayload->data, mensaje + offset, tmp_size = sizeof(BUFFERSIZEPAYLOAD));
   offset += tmp_size;
   memcpy (paquete->ip, mensaje + offset, tmp_size = sizeof(16));

   free(mensaje);

   return paquete;
}

t_stream *codificarPaquete(t_peticion *peticion){

	char *data = malloc(sizeof(char) + sizeof(short) + sizeof(int) + sizeof(BUFFERSIZEPAYLOAD)+1);
	t_stream *stream = (t_stream*)malloc(sizeof(t_stream));
	int offset =0, tmp_size = 0;

	memcpy(data, peticion->tipoPeticion,offset=sizeof(char));

	memcpy(data + offset, peticion->length, offset+=sizeof(short));

	memcpy(data + offset, peticion->sPayload->nSector, offset += sizeof(int));
	offset += sizeof(peticion->sPayload->data);
	memcpy(data + offset, peticion->sPayload->data, offset+1);

	stream->lenght = offset;
	stream->data = data;

	return stream;
}

